home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / ppp / dp-2.3 / dpd / ppp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-22  |  5.6 KB  |  258 lines

  1. /*
  2.  * Copyright (c) 1992 Purdue University
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by Purdue University.  The name of the University may not be used
  11.  * to endorse or promote products derived * from this software without
  12.  * specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include <errno.h>
  22. #include <fcntl.h>
  23. #include <signal.h>
  24. #include <sys/types.h>
  25. #include <sys/param.h>
  26. #include <sys/stream.h>
  27. #include <sys/ioctl.h>
  28. #include <sys/socket.h>
  29. #include <sys/wait.h>
  30. #include <netinet/in.h>
  31. #include <netinet/in_systm.h>
  32. #include <netinet/ip.h>
  33. #include <net/if.h>
  34. #include "dp_str.h"
  35. #include "dpd.h"
  36. #include "dp.h"
  37.  
  38. static int ppp_pid;
  39. static int aux_pid;
  40. extern void hangup();
  41.  
  42. start_ppp(rp, tty, passive, asyncmap)
  43. REMOTE *rp;
  44. char *tty;
  45. int passive,
  46.     asyncmap;
  47. {
  48.     static char        WHERE[] = "start_ppp";
  49.     char srcbuf[32], dstbuf[32], addrbuf[128],
  50.      unitbuf[16], asyncbuf[9];
  51.     char *cmds[24], **argv = cmds;
  52.  
  53.     (void)strcpy(srcbuf, inet_ntoa(rp->Address));
  54.     (void)strcpy(dstbuf, inet_ntoa(rp->DstAddress));
  55.  
  56.     (void)sprintf(unitbuf, "%d", rp->Unit);
  57.     (void)sprintf(addrbuf, "%s:%s", srcbuf, dstbuf);
  58.     (void)sprintf(asyncbuf,"%x", asyncmap);
  59.  
  60.     *argv++ = expand_dir_file("$DPBIN_DIR", PPP_PROG);
  61.     if (log_level >= DLOG_DIAG)
  62.     *argv++ = "-d";
  63.     *argv++ = "-as";
  64.     *argv++ = asyncbuf;
  65.     if (rp->PppArgs) {
  66.     char **ap;
  67.     for (ap = rp->PppArgs ; *ap ; )
  68.         *argv++ = *ap++;
  69.     }
  70.     if (passive)
  71.     *argv++ = "-p";
  72.     *argv++ = "dialup";
  73.     *argv++ = "unit";
  74.     *argv++ = unitbuf;
  75.     if (tty)
  76.     *argv++ = tty;
  77.     *argv++ = addrbuf;
  78.     *argv++ = (char *)0;
  79.     {
  80.     char cmdbuf[512], *c = cmdbuf;
  81.     *c++ = '"';
  82.     for (argv = cmds ; *argv ; argv++) {
  83.         (void)sprintf(c, "%s%c", *argv, *(argv+1) ? ' ' : '"');
  84.         c += strlen(c);
  85.     }
  86.     d_log(DLOG_GENERAL, WHERE, "Executing: %s", cmdbuf);
  87.     }
  88.  
  89.     if ((ppp_pid = fork()) == 0) {
  90.     (void)execv(cmds[0], cmds);
  91.     exit(128);
  92.     }
  93.     (void)free(cmds[0]);
  94.  
  95.     start_aux(rp);
  96.  
  97.     return ppp_pid;
  98. }
  99.  
  100. void
  101. collect_child(sig)
  102. int sig;
  103. {
  104.     int wstatus;
  105.     extern int errno, sys_nerr;
  106.     extern char *sys_errlist[];
  107.     int pid;
  108.     static char        WHERE[] = "collect_child";
  109.     char *pnm;
  110.     int lev = DLOG_DIAG;
  111.     char cnm[32];
  112.  
  113.     errno = 0;
  114.     if (ppp_pid <= 0 && aux_pid <= 0)
  115.     return;
  116.  
  117.     for ( ; ; ) {
  118.     pid = waitpid(-1, &wstatus, WNOHANG);
  119.     if (pid < 0)
  120.         switch (errno) {
  121.          case ECHILD:
  122.         d_log(DLOG_GENERAL, WHERE, "Spurious signal %d", sig);
  123.         return;
  124.          case EINTR:
  125.         continue;
  126.          default:
  127.         if (errno > 0 && errno <= sys_nerr)
  128.             d_log(DLOG_GENERAL, WHERE, "Waitpid: %s",
  129.               sys_errlist[errno]);
  130.         else
  131.             d_log(DLOG_GENERAL, WHERE, "Waitpid: %d", errno);
  132.         break;
  133.         }
  134.  
  135.     if (pid == ppp_pid) {
  136.         pnm = "PPP";
  137.         ppp_pid = 0;
  138.     }
  139.     else if (pid = aux_pid) {
  140.         pnm = "Aux Program";
  141.         aux_pid = 0;
  142.         sig = 0;
  143.     }
  144.     else {
  145.         (void)sprintf(cnm, "Unknown Child Process %d", pid);
  146.         pnm = cnm;
  147.         lev = DLOG_GENERAL;
  148.         sig = 0;
  149.     }
  150.     if (WIFEXITED(wstatus))
  151.         d_log(lev, WHERE, "%s exited with status %d", pnm,
  152.           WEXITSTATUS(wstatus));
  153.     else if (WIFSIGNALED(wstatus))
  154.         d_log(lev, WHERE, "%s exited due to signal %d", pnm,
  155.           WTERMSIG(wstatus));
  156.     if (sig)
  157.         hangup(sig);
  158.     return;
  159.     }
  160. }
  161.  
  162. void
  163. collect_ppp()
  164. {
  165.     int wstatus;
  166.     extern int errno, sys_nerr;
  167.     extern char *sys_errlist[];
  168.     static char        WHERE[] = "collect_ppp";
  169.  
  170.     errno = 0;
  171.     if (ppp_pid <= 0)
  172.     return;
  173.  
  174.     for ( ; ; ) {
  175.     if (waitpid(ppp_pid, &wstatus, 0) < 0)
  176.         switch (errno) {
  177.          case ECHILD:
  178.         d_log(DLOG_GENERAL, WHERE, "PPP already collected");
  179.         return;
  180.          case EINTR:
  181.         continue;
  182.          default:
  183.         if (errno > 0 && errno <= sys_nerr)
  184.             d_log(DLOG_GENERAL, WHERE, "Waitpid: %s",
  185.               sys_errlist[errno]);
  186.         else
  187.             d_log(DLOG_GENERAL, WHERE, "Waitpid: %d", errno);
  188.         break;
  189.         }
  190.     if (WIFEXITED(wstatus))
  191.         d_log(DLOG_DIAG, WHERE, "PPP exited with status %d",
  192.           WEXITSTATUS(wstatus));
  193.     else if (WIFSIGNALED(wstatus))
  194.         d_log(DLOG_DIAG, WHERE, "PPP exited due to signal %d",
  195.           WTERMSIG(wstatus));
  196.     ppp_pid = 0;
  197.     return;
  198.     }
  199. }
  200.  
  201. kill_ppp(sig)
  202. int sig;
  203. {
  204.     if (ppp_pid > 0)
  205.     (void)kill(ppp_pid, sig);
  206. }
  207.  
  208. /*
  209.  * Start an auxilliary program that will take advantage of the fact that
  210.  * we have an open connection to a given host.
  211.  */
  212. start_aux(rp)
  213. REMOTE *rp;
  214. {
  215.     static char        WHERE[] = "start_aux";
  216.     char *auxpath;
  217.     char *cmds[24], **argv = cmds;
  218.     int f;
  219.  
  220.     aux_pid = -1;
  221.  
  222.     if (!rp->AuxProgram)
  223.     return;
  224.  
  225.     auxpath = expand_dir_file("$DPAUX_DIR", rp->AuxProgram);
  226.     *argv++ = auxpath;
  227.  
  228.     if (rp->AuxArgs) {
  229.     char **ap;
  230.     for (ap = rp->AuxArgs ; *ap ; )
  231.         *argv++ = *ap++;
  232.     }
  233.     *argv++ = rp->Sitename;
  234.     *argv++ = (char *)0;
  235.     {
  236.     char cmdbuf[512], *c = cmdbuf;
  237.     *c++ = '"';
  238.     for (argv = cmds ; *argv ; argv++) {
  239.         (void)sprintf(c, "%s%c", *argv, *(argv+1) ? ' ' : '"');
  240.         c += strlen(c);
  241.     }
  242.     d_log(DLOG_GENERAL, WHERE, "Executing: %s", cmdbuf);
  243.     }
  244.  
  245.     if ((aux_pid = fork()) == 0) {
  246.     for (f = getdtablesize() ; f ; f--)
  247.         (void)close(f);
  248.     (void)open("/", O_RDONLY);
  249.     (void)dup2(0, 1);
  250.     (void)dup2(0, 2);
  251.     (void)setsid();
  252.     (void)execv(cmds[0], cmds);
  253.     exit(128);
  254.     }
  255.  
  256.     (void)free(auxpath);
  257. }
  258.